﻿
#region Using directives

using System;
using System.Collections;
using System.Collections.Specialized;


using System.Web.Configuration;
using System.Data;
using System.Data.Common;
using System.Configuration.Provider;

using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;

using NguyenHoa.Domains;
using NguyenHoa.Data;
using NguyenHoa.Data.Bases;

#endregion

namespace NguyenHoa.Data.SqlClient
{
	/// <summary>
	/// This class is the Sql implementation of the NetTiersProvider.
	/// </summary>
	public sealed class SqlNetTiersProvider : NguyenHoa.Data.Bases.NetTiersProvider
	{
		private static object syncRoot = new Object();
		private string _applicationName;
        private string _connectionString;
        private bool _useStoredProcedure;
        string _providerInvariantName;
		
		/// <summary>
		/// Initializes a new instance of the <see cref="SqlNetTiersProvider"/> class.
		///</summary>
		public SqlNetTiersProvider()
		{	
		}		
		
		/// <summary>
        /// Initializes the provider.
        /// </summary>
        /// <param name="name">The friendly name of the provider.</param>
        /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param>
        /// <exception cref="T:System.ArgumentNullException">The name of the provider is null.</exception>
        /// <exception cref="T:System.InvalidOperationException">An attempt is made to call <see cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"></see> on a provider after the provider has already been initialized.</exception>
        /// <exception cref="T:System.ArgumentException">The name of the provider has a length of zero.</exception>
		public override void Initialize(string name, NameValueCollection config)
        {
            // Verify that config isn't null
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            // Assign the provider a default name if it doesn't have one
            if (String.IsNullOrEmpty(name))
            {
                name = "SqlNetTiersProvider";
            }

            // Add a default "description" attribute to config if the
            // attribute doesn't exist or is empty
            if (string.IsNullOrEmpty(config["description"]))
            {
                config.Remove("description");
                config.Add("description", "NetTiers Sql provider");
            }

            // Call the base class's Initialize method
            base.Initialize(name, config);

            // Initialize _applicationName
            _applicationName = config["applicationName"];

            if (string.IsNullOrEmpty(_applicationName))
            {
                _applicationName = "/";
            }
            config.Remove("applicationName");


            #region "Initialize UseStoredProcedure"
            string storedProcedure  = config["useStoredProcedure"];
           	if (string.IsNullOrEmpty(storedProcedure))
            {
                throw new ProviderException("Empty or missing useStoredProcedure");
            }
            this._useStoredProcedure = Convert.ToBoolean(config["useStoredProcedure"]);
            config.Remove("useStoredProcedure");
            #endregion

			#region ConnectionString

			// Initialize _connectionString
			_connectionString = config["connectionString"];
			config.Remove("connectionString");

			string connect = config["connectionStringName"];
			config.Remove("connectionStringName");

			if ( String.IsNullOrEmpty(_connectionString) )
			{
				if ( String.IsNullOrEmpty(connect) )
				{
					throw new ProviderException("Empty or missing connectionStringName");
				}

				if ( DataRepository.ConnectionStrings[connect] == null )
				{
					throw new ProviderException("Missing connection string");
				}

				_connectionString = DataRepository.ConnectionStrings[connect].ConnectionString;
			}

            if ( String.IsNullOrEmpty(_connectionString) )
            {
                throw new ProviderException("Empty connection string");
			}

			#endregion
            
             #region "_providerInvariantName"

            // initialize _providerInvariantName
            this._providerInvariantName = config["providerInvariantName"];

            if (String.IsNullOrEmpty(_providerInvariantName))
            {
                throw new ProviderException("Empty or missing providerInvariantName");
            }
            config.Remove("providerInvariantName");

            #endregion

        }
		
		/// <summary>
		/// Creates a new <c cref="TransactionManager"/> instance from the current datasource.
		/// </summary>
		/// <returns></returns>
		public override TransactionManager CreateTransaction()
		{
			return new TransactionManager(this._connectionString);
		}
		
		/// <summary>
		/// Gets a value indicating whether to use stored procedure or not.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this repository use stored procedures; otherwise, <c>false</c>.
		/// </value>
		public bool UseStoredProcedure
		{
			get {return this._useStoredProcedure;}
			set {this._useStoredProcedure = value;}
		}
		
		 /// <summary>
        /// Gets or sets the connection string.
        /// </summary>
        /// <value>The connection string.</value>
		public string ConnectionString
		{
			get {return this._connectionString;}
			set {this._connectionString = value;}
		}
		
		/// <summary>
	    /// Gets or sets the invariant provider name listed in the DbProviderFactories machine.config section.
	    /// </summary>
	    /// <value>The name of the provider invariant.</value>
	    public string ProviderInvariantName
	    {
	        get { return this._providerInvariantName; }
	        set { this._providerInvariantName = value; }
	    }		
		
		///<summary>
		/// Indicates if the current <c cref="NetTiersProvider"/> implementation supports Transacton.
		///</summary>
		public override bool IsTransactionSupported
		{
			get
			{
				return true;
			}
		}

		
		#region "ActivityLogProvider"
			
		private SqlActivityLogProvider innerSqlActivityLogProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="ActivityLog"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ActivityLogProviderBase ActivityLogProvider
		{
			get
			{
				if (innerSqlActivityLogProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlActivityLogProvider == null)
						{
							this.innerSqlActivityLogProvider = new SqlActivityLogProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlActivityLogProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlActivityLogProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlActivityLogProvider SqlActivityLogProvider
		{
			get {return ActivityLogProvider as SqlActivityLogProvider;}
		}
		
		#endregion
		
		
		#region "NewsLetterProvider"
			
		private SqlNewsLetterProvider innerSqlNewsLetterProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="NewsLetter"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override NewsLetterProviderBase NewsLetterProvider
		{
			get
			{
				if (innerSqlNewsLetterProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlNewsLetterProvider == null)
						{
							this.innerSqlNewsLetterProvider = new SqlNewsLetterProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlNewsLetterProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlNewsLetterProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlNewsLetterProvider SqlNewsLetterProvider
		{
			get {return NewsLetterProvider as SqlNewsLetterProvider;}
		}
		
		#endregion
		
		
		#region "NewsCategoryProvider"
			
		private SqlNewsCategoryProvider innerSqlNewsCategoryProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="NewsCategory"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override NewsCategoryProviderBase NewsCategoryProvider
		{
			get
			{
				if (innerSqlNewsCategoryProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlNewsCategoryProvider == null)
						{
							this.innerSqlNewsCategoryProvider = new SqlNewsCategoryProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlNewsCategoryProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlNewsCategoryProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlNewsCategoryProvider SqlNewsCategoryProvider
		{
			get {return NewsCategoryProvider as SqlNewsCategoryProvider;}
		}
		
		#endregion
		
		
		#region "LanguageProvider"
			
		private SqlLanguageProvider innerSqlLanguageProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Language"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override LanguageProviderBase LanguageProvider
		{
			get
			{
				if (innerSqlLanguageProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlLanguageProvider == null)
						{
							this.innerSqlLanguageProvider = new SqlLanguageProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlLanguageProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlLanguageProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlLanguageProvider SqlLanguageProvider
		{
			get {return LanguageProvider as SqlLanguageProvider;}
		}
		
		#endregion
		
		
		#region "NewsProvider"
			
		private SqlNewsProvider innerSqlNewsProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="News"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override NewsProviderBase NewsProvider
		{
			get
			{
				if (innerSqlNewsProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlNewsProvider == null)
						{
							this.innerSqlNewsProvider = new SqlNewsProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlNewsProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlNewsProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlNewsProvider SqlNewsProvider
		{
			get {return NewsProvider as SqlNewsProvider;}
		}
		
		#endregion
		
		
		#region "MainMenuProvider"
			
		private SqlMainMenuProvider innerSqlMainMenuProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="MainMenu"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override MainMenuProviderBase MainMenuProvider
		{
			get
			{
				if (innerSqlMainMenuProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlMainMenuProvider == null)
						{
							this.innerSqlMainMenuProvider = new SqlMainMenuProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlMainMenuProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlMainMenuProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlMainMenuProvider SqlMainMenuProvider
		{
			get {return MainMenuProvider as SqlMainMenuProvider;}
		}
		
		#endregion
		
		
		#region "ProductProvider"
			
		private SqlProductProvider innerSqlProductProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Product"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ProductProviderBase ProductProvider
		{
			get
			{
				if (innerSqlProductProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlProductProvider == null)
						{
							this.innerSqlProductProvider = new SqlProductProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlProductProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlProductProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlProductProvider SqlProductProvider
		{
			get {return ProductProvider as SqlProductProvider;}
		}
		
		#endregion
		
		
		#region "NewsCategoryLocaleProvider"
			
		private SqlNewsCategoryLocaleProvider innerSqlNewsCategoryLocaleProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="NewsCategoryLocale"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override NewsCategoryLocaleProviderBase NewsCategoryLocaleProvider
		{
			get
			{
				if (innerSqlNewsCategoryLocaleProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlNewsCategoryLocaleProvider == null)
						{
							this.innerSqlNewsCategoryLocaleProvider = new SqlNewsCategoryLocaleProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlNewsCategoryLocaleProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlNewsCategoryLocaleProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlNewsCategoryLocaleProvider SqlNewsCategoryLocaleProvider
		{
			get {return NewsCategoryLocaleProvider as SqlNewsCategoryLocaleProvider;}
		}
		
		#endregion
		
		
		#region "SubMenuProvider"
			
		private SqlSubMenuProvider innerSqlSubMenuProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="SubMenu"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override SubMenuProviderBase SubMenuProvider
		{
			get
			{
				if (innerSqlSubMenuProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlSubMenuProvider == null)
						{
							this.innerSqlSubMenuProvider = new SqlSubMenuProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlSubMenuProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlSubMenuProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlSubMenuProvider SqlSubMenuProvider
		{
			get {return SubMenuProvider as SqlSubMenuProvider;}
		}
		
		#endregion
		
		
		#region "ProductLocaleProvider"
			
		private SqlProductLocaleProvider innerSqlProductLocaleProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="ProductLocale"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ProductLocaleProviderBase ProductLocaleProvider
		{
			get
			{
				if (innerSqlProductLocaleProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlProductLocaleProvider == null)
						{
							this.innerSqlProductLocaleProvider = new SqlProductLocaleProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlProductLocaleProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlProductLocaleProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlProductLocaleProvider SqlProductLocaleProvider
		{
			get {return ProductLocaleProvider as SqlProductLocaleProvider;}
		}
		
		#endregion
		
		
		#region "SurveyDetailProvider"
			
		private SqlSurveyDetailProvider innerSqlSurveyDetailProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="SurveyDetail"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override SurveyDetailProviderBase SurveyDetailProvider
		{
			get
			{
				if (innerSqlSurveyDetailProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlSurveyDetailProvider == null)
						{
							this.innerSqlSurveyDetailProvider = new SqlSurveyDetailProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlSurveyDetailProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlSurveyDetailProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlSurveyDetailProvider SqlSurveyDetailProvider
		{
			get {return SurveyDetailProvider as SqlSurveyDetailProvider;}
		}
		
		#endregion
		
		
		#region "UserProvider"
			
		private SqlUserProvider innerSqlUserProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="User"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override UserProviderBase UserProvider
		{
			get
			{
				if (innerSqlUserProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlUserProvider == null)
						{
							this.innerSqlUserProvider = new SqlUserProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlUserProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlUserProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlUserProvider SqlUserProvider
		{
			get {return UserProvider as SqlUserProvider;}
		}
		
		#endregion
		
		
		#region "SurveyProvider"
			
		private SqlSurveyProvider innerSqlSurveyProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Survey"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override SurveyProviderBase SurveyProvider
		{
			get
			{
				if (innerSqlSurveyProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlSurveyProvider == null)
						{
							this.innerSqlSurveyProvider = new SqlSurveyProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlSurveyProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlSurveyProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlSurveyProvider SqlSurveyProvider
		{
			get {return SurveyProvider as SqlSurveyProvider;}
		}
		
		#endregion
		
		
		#region "SubMenuLocaleProvider"
			
		private SqlSubMenuLocaleProvider innerSqlSubMenuLocaleProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="SubMenuLocale"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override SubMenuLocaleProviderBase SubMenuLocaleProvider
		{
			get
			{
				if (innerSqlSubMenuLocaleProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlSubMenuLocaleProvider == null)
						{
							this.innerSqlSubMenuLocaleProvider = new SqlSubMenuLocaleProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlSubMenuLocaleProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlSubMenuLocaleProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlSubMenuLocaleProvider SqlSubMenuLocaleProvider
		{
			get {return SubMenuLocaleProvider as SqlSubMenuLocaleProvider;}
		}
		
		#endregion
		
		
		#region "SettingProvider"
			
		private SqlSettingProvider innerSqlSettingProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Setting"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override SettingProviderBase SettingProvider
		{
			get
			{
				if (innerSqlSettingProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlSettingProvider == null)
						{
							this.innerSqlSettingProvider = new SqlSettingProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlSettingProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlSettingProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlSettingProvider SqlSettingProvider
		{
			get {return SettingProvider as SqlSettingProvider;}
		}
		
		#endregion
		
		
		#region "MultimediaProvider"
			
		private SqlMultimediaProvider innerSqlMultimediaProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Multimedia"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override MultimediaProviderBase MultimediaProvider
		{
			get
			{
				if (innerSqlMultimediaProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlMultimediaProvider == null)
						{
							this.innerSqlMultimediaProvider = new SqlMultimediaProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlMultimediaProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlMultimediaProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlMultimediaProvider SqlMultimediaProvider
		{
			get {return MultimediaProvider as SqlMultimediaProvider;}
		}
		
		#endregion
		
		
		#region "MenuTypeProvider"
			
		private SqlMenuTypeProvider innerSqlMenuTypeProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="MenuType"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override MenuTypeProviderBase MenuTypeProvider
		{
			get
			{
				if (innerSqlMenuTypeProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlMenuTypeProvider == null)
						{
							this.innerSqlMenuTypeProvider = new SqlMenuTypeProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlMenuTypeProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlMenuTypeProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlMenuTypeProvider SqlMenuTypeProvider
		{
			get {return MenuTypeProvider as SqlMenuTypeProvider;}
		}
		
		#endregion
		
		
		#region "ContactInfoProvider"
			
		private SqlContactInfoProvider innerSqlContactInfoProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="ContactInfo"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override ContactInfoProviderBase ContactInfoProvider
		{
			get
			{
				if (innerSqlContactInfoProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlContactInfoProvider == null)
						{
							this.innerSqlContactInfoProvider = new SqlContactInfoProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlContactInfoProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlContactInfoProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlContactInfoProvider SqlContactInfoProvider
		{
			get {return ContactInfoProvider as SqlContactInfoProvider;}
		}
		
		#endregion
		
		
		#region "AlbumProvider"
			
		private SqlAlbumProvider innerSqlAlbumProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Album"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override AlbumProviderBase AlbumProvider
		{
			get
			{
				if (innerSqlAlbumProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlAlbumProvider == null)
						{
							this.innerSqlAlbumProvider = new SqlAlbumProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlAlbumProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlAlbumProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlAlbumProvider SqlAlbumProvider
		{
			get {return AlbumProvider as SqlAlbumProvider;}
		}
		
		#endregion
		
		
		#region "AdvertiseLocaleProvider"
			
		private SqlAdvertiseLocaleProvider innerSqlAdvertiseLocaleProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="AdvertiseLocale"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override AdvertiseLocaleProviderBase AdvertiseLocaleProvider
		{
			get
			{
				if (innerSqlAdvertiseLocaleProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlAdvertiseLocaleProvider == null)
						{
							this.innerSqlAdvertiseLocaleProvider = new SqlAdvertiseLocaleProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlAdvertiseLocaleProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlAdvertiseLocaleProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlAdvertiseLocaleProvider SqlAdvertiseLocaleProvider
		{
			get {return AdvertiseLocaleProvider as SqlAdvertiseLocaleProvider;}
		}
		
		#endregion
		
		
		#region "AdvertisementProvider"
			
		private SqlAdvertisementProvider innerSqlAdvertisementProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Advertisement"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override AdvertisementProviderBase AdvertisementProvider
		{
			get
			{
				if (innerSqlAdvertisementProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlAdvertisementProvider == null)
						{
							this.innerSqlAdvertisementProvider = new SqlAdvertisementProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlAdvertisementProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlAdvertisementProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlAdvertisementProvider SqlAdvertisementProvider
		{
			get {return AdvertisementProvider as SqlAdvertisementProvider;}
		}
		
		#endregion
		
		
		#region "CurrencyProvider"
			
		private SqlCurrencyProvider innerSqlCurrencyProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Currency"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override CurrencyProviderBase CurrencyProvider
		{
			get
			{
				if (innerSqlCurrencyProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlCurrencyProvider == null)
						{
							this.innerSqlCurrencyProvider = new SqlCurrencyProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlCurrencyProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlCurrencyProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlCurrencyProvider SqlCurrencyProvider
		{
			get {return CurrencyProvider as SqlCurrencyProvider;}
		}
		
		#endregion
		
		
		#region "AlbumLocaleProvider"
			
		private SqlAlbumLocaleProvider innerSqlAlbumLocaleProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="AlbumLocale"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override AlbumLocaleProviderBase AlbumLocaleProvider
		{
			get
			{
				if (innerSqlAlbumLocaleProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlAlbumLocaleProvider == null)
						{
							this.innerSqlAlbumLocaleProvider = new SqlAlbumLocaleProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlAlbumLocaleProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlAlbumLocaleProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlAlbumLocaleProvider SqlAlbumLocaleProvider
		{
			get {return AlbumLocaleProvider as SqlAlbumLocaleProvider;}
		}
		
		#endregion
		
		
		#region "GroupProvider"
			
		private SqlGroupProvider innerSqlGroupProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Group"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GroupProviderBase GroupProvider
		{
			get
			{
				if (innerSqlGroupProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGroupProvider == null)
						{
							this.innerSqlGroupProvider = new SqlGroupProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGroupProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlGroupProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGroupProvider SqlGroupProvider
		{
			get {return GroupProvider as SqlGroupProvider;}
		}
		
		#endregion
		
		
		#region "CustomerOpinionProvider"
			
		private SqlCustomerOpinionProvider innerSqlCustomerOpinionProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="CustomerOpinion"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override CustomerOpinionProviderBase CustomerOpinionProvider
		{
			get
			{
				if (innerSqlCustomerOpinionProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlCustomerOpinionProvider == null)
						{
							this.innerSqlCustomerOpinionProvider = new SqlCustomerOpinionProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlCustomerOpinionProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlCustomerOpinionProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlCustomerOpinionProvider SqlCustomerOpinionProvider
		{
			get {return CustomerOpinionProvider as SqlCustomerOpinionProvider;}
		}
		
		#endregion
		
		
		#region "MainMenuLocaleProvider"
			
		private SqlMainMenuLocaleProvider innerSqlMainMenuLocaleProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="MainMenuLocale"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override MainMenuLocaleProviderBase MainMenuLocaleProvider
		{
			get
			{
				if (innerSqlMainMenuLocaleProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlMainMenuLocaleProvider == null)
						{
							this.innerSqlMainMenuLocaleProvider = new SqlMainMenuLocaleProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlMainMenuLocaleProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlMainMenuLocaleProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlMainMenuLocaleProvider SqlMainMenuLocaleProvider
		{
			get {return MainMenuLocaleProvider as SqlMainMenuLocaleProvider;}
		}
		
		#endregion
		
		
		#region "FunctionProvider"
			
		private SqlFunctionProvider innerSqlFunctionProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="Function"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override FunctionProviderBase FunctionProvider
		{
			get
			{
				if (innerSqlFunctionProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlFunctionProvider == null)
						{
							this.innerSqlFunctionProvider = new SqlFunctionProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlFunctionProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlFunctionProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlFunctionProvider SqlFunctionProvider
		{
			get {return FunctionProvider as SqlFunctionProvider;}
		}
		
		#endregion
		
		
		#region "HtmlContentProvider"
			
		private SqlHtmlContentProvider innerSqlHtmlContentProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="HtmlContent"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override HtmlContentProviderBase HtmlContentProvider
		{
			get
			{
				if (innerSqlHtmlContentProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlHtmlContentProvider == null)
						{
							this.innerSqlHtmlContentProvider = new SqlHtmlContentProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlHtmlContentProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlHtmlContentProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlHtmlContentProvider SqlHtmlContentProvider
		{
			get {return HtmlContentProvider as SqlHtmlContentProvider;}
		}
		
		#endregion
		
		
		#region "UserGroupProvider"
			
		private SqlUserGroupProvider innerSqlUserGroupProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="UserGroup"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override UserGroupProviderBase UserGroupProvider
		{
			get
			{
				if (innerSqlUserGroupProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlUserGroupProvider == null)
						{
							this.innerSqlUserGroupProvider = new SqlUserGroupProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlUserGroupProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlUserGroupProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlUserGroupProvider SqlUserGroupProvider
		{
			get {return UserGroupProvider as SqlUserGroupProvider;}
		}
		
		#endregion
		
		
		#region "GroupPermissionProvider"
			
		private SqlGroupPermissionProvider innerSqlGroupPermissionProvider;

		///<summary>
		/// This class is the Data Access Logic Component for the <see cref="GroupPermission"/> business entity.
		/// It exposes CRUD methods as well as selecting on index, foreign keys and custom stored procedures.
		///</summary>
		/// <value></value>
		public override GroupPermissionProviderBase GroupPermissionProvider
		{
			get
			{
				if (innerSqlGroupPermissionProvider == null) 
				{
					lock (syncRoot) 
					{
						if (innerSqlGroupPermissionProvider == null)
						{
							this.innerSqlGroupPermissionProvider = new SqlGroupPermissionProvider(_connectionString, _useStoredProcedure, _providerInvariantName);
						}
					}
				}
				return innerSqlGroupPermissionProvider;
			}
		}
		
		/// <summary>
		/// Gets the current <c cref="SqlGroupPermissionProvider"/>.
		/// </summary>
		/// <value></value>
		public SqlGroupPermissionProvider SqlGroupPermissionProvider
		{
			get {return GroupPermissionProvider as SqlGroupPermissionProvider;}
		}
		
		#endregion
		
		
		
		#region "General data access methods"

		#region "ExecuteNonQuery"
		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteNonQuery(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteNonQuery(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		public override void ExecuteNonQuery(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			database.ExecuteNonQuery(commandWrapper);	
			
		}

		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		public override void ExecuteNonQuery(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			database.ExecuteNonQuery(commandWrapper, transactionManager.TransactionObject);	
		}


		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteNonQuery(commandType, commandText);	
		}
		/// <summary>
		/// Executes the non query.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override int ExecuteNonQuery(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteNonQuery(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#region "ExecuteDataReader"
		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteReader(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			Database database = transactionManager.Database;
			return database.ExecuteReader(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteReader(commandWrapper);	
		}

		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			Database database = transactionManager.Database;
			return database.ExecuteReader(commandWrapper, transactionManager.TransactionObject);	
		}


		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteReader(commandType, commandText);	
		}
		/// <summary>
		/// Executes the reader.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override IDataReader ExecuteReader(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteReader(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#region "ExecuteDataSet"
		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteDataSet(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			Database database = transactionManager.Database;
			return database.ExecuteDataSet(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteDataSet(commandWrapper);	
		}

		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			Database database = transactionManager.Database;
			return database.ExecuteDataSet(commandWrapper, transactionManager.TransactionObject);	
		}


		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteDataSet(commandType, commandText);	
		}
		/// <summary>
		/// Executes the data set.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override DataSet ExecuteDataSet(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteDataSet(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#region "ExecuteScalar"
		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override object ExecuteScalar(string storedProcedureName, params object[] parameterValues)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteScalar(storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="storedProcedureName">Name of the stored procedure.</param>
		/// <param name="parameterValues">The parameter values.</param>
		/// <returns></returns>
		public override object ExecuteScalar(TransactionManager transactionManager, string storedProcedureName, params object[] parameterValues)
		{
			Database database = transactionManager.Database;
			return database.ExecuteScalar(transactionManager.TransactionObject, storedProcedureName, parameterValues);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override object ExecuteScalar(DbCommand commandWrapper)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);			
			return database.ExecuteScalar(commandWrapper);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandWrapper">The command wrapper.</param>
		/// <returns></returns>
		public override object ExecuteScalar(TransactionManager transactionManager, DbCommand commandWrapper)
		{
			Database database = transactionManager.Database;
			return database.ExecuteScalar(commandWrapper, transactionManager.TransactionObject);	
		}

		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override object ExecuteScalar(CommandType commandType, string commandText)
		{
			SqlDatabase database = new SqlDatabase(this._connectionString);
			return database.ExecuteScalar(commandType, commandText);	
		}
		/// <summary>
		/// Executes the scalar.
		/// </summary>
		/// <param name="transactionManager">The transaction manager.</param>
		/// <param name="commandType">Type of the command.</param>
		/// <param name="commandText">The command text.</param>
		/// <returns></returns>
		public override object ExecuteScalar(TransactionManager transactionManager, CommandType commandType, string commandText)
		{
			Database database = transactionManager.Database;			
			return database.ExecuteScalar(transactionManager.TransactionObject , commandType, commandText);				
		}
		#endregion

		#endregion


	}
}
